package com.ruoyi.system.controller;



import java.io.IOException;
import java.util.Set;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.event.AnalysisEventListener;
import com.ruoyi.common.utils.easyExcel.EasyExcelListenerFactory;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.SysModifyUser;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.message.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import com.fasterxml.jackson.annotation.JsonView;
import com.ruoyi.common.annotation.LoginUser;
import com.ruoyi.common.auth.annotation.HasPermissions;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.log.annotation.OperLog;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.common.utils.RandomUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.system.mapper.SysRoleMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.ISysMenuService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.util.PasswordUtil;

import cn.hutool.core.convert.Convert;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 用户 提供者
 *
 * @author zmr
 * @date 2019-05-20
 */
@RestController
@RequestMapping("user")
@Slf4j
public class SysUserController extends BaseController
{
    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private ISysMenuService sysMenuService;

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    /**
     * 查询用户
     */
    @GetMapping("get/{userId}")
    public SysUser get(@PathVariable("userId") Long userId)
    {
        return sysUserService.selectUserById(userId);
    }

    /**
     * 查询用户(批量)
     */
    @GetMapping("getlist/{userIdlist}")
    public R get(@PathVariable("userIdlist") String userIdlist)
    {
        return jacResult(sysUserService.selectUserByIdlist(userIdlist));
    }

    /**
     * 查询用户
     */
    @PostMapping("getName")
    @JsonView(value = SysUser.getName.class)
    public R getNameByName(@RequestBody SysUser sysUser)
    {

        Integer pageNum = sysUser.getPageNum();
        Integer pageSize = sysUser.getPageSize();
        String sortField = sysUser.getSortField();
        String sortOrder = sysUser.getSortOrder();
        startPage(pageNum,pageSize,sortField,sortOrder);
        return result(sysUserService.selectUserNameByName(sysUser));
    }

    /**
     * 通过用户id获取供应商字符串
     * @return
     */
    @GetMapping("getVendorCodes/{userId}")
    public Map<String,Object> getVendorCodes(@PathVariable("userId") String userId)
    {
        Map<String, Object> r = new HashMap<String, Object>();
        try {
            String[] s = sysUserService.selectVendorCodes(userId);
            r.put("msg", "success");
            r.put("code", "0");
            r.put("rows", s);
            return r;
        } catch (Exception e) {
            log.error("error",e);
//            r.put("msg", e);
            r.put("code", "500");
            return r;
        }
    }

    /**
     * 查询用户信息业务前台
     */
    @GetMapping("info")
    public Map<String, Object> info(@LoginUser SysUser sysUser)
    {
        try {
            sysUser.setButtons(sysMenuService.selectPermsByUserId(sysUser.getUserId()));
            Map<String, Object> result = new HashMap<String, Object>();
            result.put("msg", "success");
            result.put("code", "0");
            List<SysUser> list = new ArrayList<SysUser>();
            list.add(sysUser);
            result.put("rows", list);
            return result;
        } catch (Exception e) {
            Map<String, Object> result = new HashMap<String, Object>();
            result.put("msg", e);
            result.put("code", "500");
            return result;
        }
    }

    /**
     * 查询用户信息system
     */
    @GetMapping("sysInfo")
    public SysUser sysInfo(@LoginUser SysUser sysUser)
    {
        sysUser.setButtons(sysMenuService.selectPermsByUserId(sysUser.getUserId()));
        return sysUser;
    }

    /**
     * 查询用户
     */
    @GetMapping("find/{username}")
    public SysUser findByUsername(@PathVariable("username") String username)
    {
        return sysUserService.selectUserByLoginName(username);
    }

    /**
     * 查询拥有当前角色的所有用户
     */
    @GetMapping("hasRoles")
    public Set<Long> hasRoles(String roleIds)
    {
        Long[] arr=Convert.toLongArray(roleIds);
        return sysUserService.selectUserIdsHasRoles(arr);
    }

    /**
     * 查询所有当前部门中的用户
     */
    @GetMapping("inDepts")
    public Set<Long> inDept(String  deptIds)
    {
        Long[] arr=Convert.toLongArray(deptIds);
        return sysUserService.selectUserIdsInDepts(arr);
    }

    /**
     * 查询用户列表
     */
    @GetMapping("list")
    public R list(SysUser sysUser)
    {
        startPage();
        return result(sysUserService.selectUserList(sysUser));
    }

    @GetMapping("checkMail")
    public Map<String,Object> checkMail(SysUser sysUser)
    {
        Map<String,Object> m = new HashMap<>();
        if (UserConstants.USER_EMAIL_NOT_UNIQUE.equals(sysUserService.checkEmailUnique(sysUser)))
        {
            m.put("code", 505);
            m.put("msg", sysUser.getEmail()  + "邮箱账号已存在!");
            return m;
        }
        m.put("code", 0);
        m.put("msg", "success");
        return m;
    }

    /**
     * 新增保存用户
     */
    @HasPermissions("system:user:add")
    @PostMapping("save")
    @OperLog(title = "用户管理", businessType = BusinessType.INSERT)
    public R addSave(@RequestBody SysUser sysUser)
    {
        if (UserConstants.USER_NAME_NOT_UNIQUE.equals(sysUserService.checkLoginNameUnique(sysUser.getLoginName())))
        {
            return R.error("新增用户'" + sysUser.getLoginName() + "'失败，登录账号已存在");
        }
        else if (UserConstants.USER_PHONE_NOT_UNIQUE.equals(sysUserService.checkPhoneUnique(sysUser)))
        {
            return R.error("新增用户'" + sysUser.getLoginName() + "'失败，手机号码已存在");
        }
        sysUser.setPassword(sysUser.getLoginName() + "jac,123");
        sysUser.setSalt(RandomUtil.randomStr(6));
        sysUser.setPassword(
                PasswordUtil.encryptPassword(sysUser.getLoginName(), sysUser.getPassword(), sysUser.getSalt()));
        sysUser.setCreateBy(getLoginName());
        return toAjax(sysUserService.insertUser(sysUser));
    }


    /**
     * excel批量新增审核用户 2021/01/03
     */
//    @HasPermissions("system:user:add")
    @PostMapping("batchImportUser")
//    @OperLog(title = "用户管理", businessType = BusinessType.INSERT)
    @Transactional(rollbackFor = Exception.class)
    public R batchImportUser(MultipartFile file) throws IOException {
        StringBuilder stringBuilder = new StringBuilder();
        int count = 0;
        List<SysUser> list = new ArrayList<>();//此list用来存储导入文件中的每行数据
        EasyExcelListenerFactory<SysUser> tf = new EasyExcelListenerFactory<>(list);
        AnalysisEventListener listener = tf.getListener();
        EasyExcel.read(file.getInputStream(),SysUser.class,listener).sheet().doRead();//执行完此句后list内就存了文件中数据

        for (SysUser sysUser:list){
            if (UserConstants.USER_NAME_NOT_UNIQUE.equals(sysUserService.checkLoginNameUnique(sysUser.getLoginName())))
            {
                logger.error("批量导入用户" + sysUser.getLoginName() + "'失败，登录账号已存在");
                stringBuilder.append("---批量导入用户" + sysUser.getLoginName() + "'失败，登录账号已存在---");
                count++;
                continue;
            }else if (UserConstants.USER_PHONE_NOT_UNIQUE.equals(sysUserService.checkPhoneUnique(sysUser)))
            {
                logger.error("批量导入用户'" + sysUser.getLoginName() + "'失败，手机号码已存在");
                stringBuilder.append("---批量导入用户" + sysUser.getLoginName() + "'失败，登录账号已存在---");
                count++;
                continue;
            }
            sysUser.setDeptId(422l);//默认放在“其他”部门
            sysUser.setPassword(sysUser.getLoginName() + "2020");
            sysUser.setSalt(RandomUtil.randomStr(6));
            sysUser.setPassword(
                    PasswordUtil.encryptPassword(sysUser.getLoginName(), sysUser.getPassword(), sysUser.getSalt()));
            sysUser.setCreateBy(getLoginName());
            sysUserService.insertUser(sysUser);//实际导入过程，可以根据自身情况进行相应导入成功失败判断，并返回给前台
        }
        if(count==0){
            return R.ok();
        }else{
            return resultObject(stringBuilder);
        }
    }

    /**
     * 批量重置密码(无密码)
     * @param user
     * @return
     */
//    @HasPermissions("system:user:resetPwd")
//    @OperLog(title = "重置密码", businessType = BusinessType.UPDATE)
    @PostMapping("/resetPwdSaveBatch")
    @Transactional(rollbackFor = Exception.class)
    public void resetPwdSaveBatch()
    {
//        if (null != user.getUserId() && SysUser.isAdmin(user.getUserId()))
//        {
//            return R.error("不允许修改超级管理员用户");
//        }
        List<SysUser> sysUsers = sysUserService.selectWithoutPasswordUser();
        for (SysUser sysUser:sysUsers){
//            sysUser.setDeptId(141l);//默认放在“其他”部门
            sysUser.setPassword(sysUser.getLoginName() + "2020");
            sysUser.setSalt(RandomUtil.randomStr(6));
            sysUser.setPassword(
                    PasswordUtil.encryptPassword(sysUser.getLoginName(), sysUser.getPassword(), sysUser.getSalt()));
            sysUser.setCreateBy(getLoginName());
            sysUserService.updateUserInfo(sysUser);//实际导入过程，可以根据自身情况进行相应导入成功失败判断，并返回给前台
        }

    }


    @GetMapping("/importTemplate")
    @ResponseBody
    @ApiOperation(value = "get importtemple",notes = "test")
    public void importTemplate(HttpServletResponse response, HttpServletRequest request)
    {
        try {
            response.setHeader("code", "0");
            String filename = "审核人员用户导入模板.xlsx";
            response.setCharacterEncoding("utf-8");
            response.setContentType("multipart/form-data");
            response.setHeader("Content-Disposition",
                    "attachment;fileName=" + FileUtils.setFileDownloadHeader(request, filename));
            ExcelUtil<SysUser> util = new ExcelUtil<>(SysUser.class);
            util.importTemplateExcel("用户",response.getOutputStream());
        } catch (Exception e) {
            logger.error("下载文件失败", e);
            response.setHeader("code", "500");
        }
    }

    /**
     * 插入用户与供应商id对应关系
     * 默认给调用此接口的用户绑定‘供应商’部门
     */
    @PostMapping("insertSuId")
    public R insertSuId(@RequestBody SysUser sysUser)
    {
        sysUser.setDeptId(2l);
        sysUserService.updateUserInfo(sysUser);
        return toAjax(sysUserService.insertSuId(sysUser.getUserId(), sysUser.getSupplierId()));
    }

    /**
     * 用户注册
     */
    @PostMapping("register")
    @OperLog(title = "用户注册", businessType = BusinessType.INSERT)
    public R addRegister(@RequestBody SysUser sysUser)
    {
        sysUser.setUserType("01");
        sysUser.setUserName(sysUser.getLoginName());
        List<Long> roleids = new ArrayList<Long>();
        roleids.add(sysRoleMapper.selectRoleNameByRoleId("注册用户"));
        sysUser.setRoleIds(roleids);
        if (UserConstants.USER_NAME_NOT_UNIQUE.equals(sysUserService.checkLoginNameUnique(sysUser.getLoginName())))
        {
            return R.error("注册失败，登录账号已存在");
        }
        else if (UserConstants.USER_PHONE_NOT_UNIQUE.equals(sysUserService.checkPhoneUnique(sysUser)))
        {
            return R.error("注册失败，手机号码已存在");
        }
        sysUser.setSalt(RandomUtil.randomStr(6));
        sysUser.setPassword(
                PasswordUtil.encryptPassword(sysUser.getLoginName(), sysUser.getPassword(), sysUser.getSalt()));
        sysUser.setCreateBy(getLoginName());
        sysUserService.insertUser(sysUser);
        return jacResultString("userId",sysUserMapper.selectUseridByLoginName(sysUser.getLoginName()).toString());
    }

    /**
     * 修改保存用户
     */
    @HasPermissions("system:user:edit")
    @OperLog(title = "用户管理", businessType = BusinessType.UPDATE)
    @PostMapping("update")
    public R editSave(@RequestBody SysUser sysUser)
    {
        if (null != sysUser.getUserId() && SysUser.isAdmin(sysUser.getUserId()))
        {
            return R.error("不允许修改超级管理员用户");
        }
        else if (UserConstants.USER_PHONE_NOT_UNIQUE.equals(sysUserService.checkPhoneUnique(sysUser)))
        {
            return R.error("修改用户'" + sysUser.getLoginName() + "'失败，手机号码已存在");
        }
        else if (UserConstants.USER_EMAIL_NOT_UNIQUE.equals(sysUserService.checkEmailUnique(sysUser)))
        {
            return R.error("修改用户'" + sysUser.getLoginName() + "'失败，邮箱账号已存在");
        }
        return toAjax(sysUserService.updateUser(sysUser));
    }

    /**
     * 修改用户信息
     * @param sysUser
     * @return
     * @author zmr
     */
    @HasPermissions("system:user:info")
    @PostMapping("update/info")
    @OperLog(title = "用户管理", businessType = BusinessType.UPDATE)
    public R updateInfo(@RequestBody SysUser sysUser, HttpServletRequest request)
    {
        sysUser.setUserId(Long.valueOf(request.getHeader("current_id")));
        return toAjax(sysUserService.updateUserInfo(sysUser));
    }

    /**
     * 记录登陆信息
     * @param sysUser
     * @return
     * @author zmr
     */
    @PostMapping("update/login")
    public R updateLoginRecord(@RequestBody SysUser sysUser)
    {
        return toAjax(sysUserService.updateUser(sysUser));
    }

    /**
     * 供应商编码下发时更新用户账号
     * @param sysUser
     * @return
     * @author zmr
     */
    @PostMapping("vendorcodeUpdate")
    public R vendorcodeUpdate(@RequestBody SysUser sysUser)
    {
        sysUser.setPassword(sysUser.getLoginName() + "jac,123");
        sysUser.setSalt(RandomUtil.randomStr(6));
        sysUser.setPassword(
                PasswordUtil.encryptPassword(sysUser.getLoginName(), sysUser.getPassword(), sysUser.getSalt()));
        sysUser.setCreateBy(getLoginName());
        String result = sysUserService.insertOldUser(sysUser.getUserId());
        if (!"1".equals(result))
        {
            log.error(result);
            return R.error(result);
        }
        return toAjax(sysUserService.updateUser(sysUser));
    }

    @HasPermissions("system:user:resetPwd")
    @OperLog(title = "重置密码", businessType = BusinessType.UPDATE)
    @PostMapping("/resetPwd")
    public R resetPwdSave(@RequestBody SysUser user)
    {
//        if (null != user.getUserId() && SysUser.isAdmin(user.getUserId()))
//        {
//            return R.error("不允许修改超级管理员用户");
//        }
        user.setSalt(RandomUtil.randomStr(6));
        user.setPassword(PasswordUtil.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt()));
        return toAjax(sysUserService.resetUserPwd(user));
    }


    /**
     * 修改密码
     * @param user
     * @return
     */
    @HasPermissions("system:user:info")
    @OperLog(title = "修改密码", businessType = BusinessType.UPDATE)
    @PostMapping("/modifyPwd")
    public R modifyPwdSave(@RequestBody SysModifyUser sysmodifyuser)
    {
        SysUser user = sysUserService.selectUserById(sysmodifyuser.getUserId());
        if (null != user.getUserId() && SysUser.isAdmin(user.getUserId()))
        {
            return R.error("不允许修改超级管理员用户");
        }
        if(PasswordUtil.encryptPassword(sysmodifyuser.getLoginName(), sysmodifyuser.getOldPwd(), user.getSalt()).equals(user.getPassword())){
            user.setSalt(RandomUtil.randomStr(6));
            user.setPassword(PasswordUtil.encryptPassword(sysmodifyuser.getLoginName(), sysmodifyuser.getNewPwd(), user.getSalt()));
            return toAjax(sysUserService.resetUserPwd(user));
        }else{
            return R.error("原密码错误！");
        }
    }

    /**
     * 修改状态
     * @param sysUser
     * @return
     * @author zmr
     */
    @HasPermissions("system:user:edit")
    @PostMapping("status")
    @OperLog(title = "用户管理", businessType = BusinessType.UPDATE)
    public R status(@RequestBody SysUser user)
    {
        if (null != user.getUserId() && SysUser.isAdmin(user.getUserId()))
        {
            return R.error("不允许修改超级管理员用户");
        }
        return toAjax(sysUserService.changeStatus(user));
    }

    /**
     * 删除用户
     * @throws Exception
     */
    @HasPermissions("system:user:remove")
    @OperLog(title = "用户管理", businessType = BusinessType.DELETE)
    @PostMapping("remove")
    public R remove(String ids) throws Exception
    {
        return toAjax(sysUserService.deleteUserByIds(ids));
    }
}
